package utils

import (
	"bytes"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

func SuccessJSON(context *gin.Context, data interface{}) {
	context.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    data,
	})
}

func ErrorJSON(context *gin.Context, msg interface{}) {
	context.JSON(http.StatusOK, gin.H{
		"code":    1,
		"message": msg,
		"data":    nil,
	})
}

func ClientFailJSON(context *gin.Context) {
	context.JSON(http.StatusBadRequest, nil)
}

func GetRealIP(request *http.Request) string {
	proxyIps := strings.Split(request.Header.Get("X-Forwarded-For"), ", ")
	realIp := proxyIps[len(proxyIps)-1]
	return realIp
}

func CheckError(errs ...error) {
	for _, err := range errs {
		if err != nil {
			panic(err)
		}
	}
}

func NewInt(value int) *int {
	re := new(int)
	*re = value
	return re
}

func NewInt64(value int64) *int64 {
	re := new(int64)
	*re = value
	return re
}

func NewString(value string) *string {
	re := new(string)
	*re = value
	return re
}

func JsonToMap(jsonStr string) (map[string]interface{}, error) {
	m := make(map[string]interface{})
	err := json.Unmarshal([]byte(jsonStr), &m)
	if err != nil {
		return nil, err
	}
	return m, nil
}

func JsonToMaps(jsonStr string) ([]map[string]interface{}, error) {
	m := make([]map[string]interface{}, 0)
	err := json.Unmarshal([]byte(jsonStr), &m)
	if err != nil {
		return nil, err
	}
	return m, nil
}

func RandStr(n int) string {
	var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

func Int64ToString(value int64) string {
	return strconv.FormatInt(value, 10)
}

func NilWrite0(m map[string]interface{}, s ...string) {
	for _, item := range s {
		if m[item] == nil {
			m[item] = 0
		}
	}
}

func GetRequestBody(context *gin.Context) string {
	data, _ := ioutil.ReadAll(context.Request.Body)
	context.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))
	return string(data)
}

func IsAdmin(context *gin.Context) bool {
	path := context.Request.URL.Path
	return StringPrefix(path, "/admin") || path == "/auth/AdminLogin"
}

func StringToInt64(s string) (int64, error) {
	return strconv.ParseInt(s, 10, 64)
}

func StringPrefix(s, prefix string) bool {
	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}

func GetErrorJsonFlag() string {
	return "[errorJson]"
}

func PanicWithErrorJson(err string) {
	panic(GetErrorJsonFlag() + err)
}

func PanicWithErrorJsonWhenTrue(judge bool, err string) {
	if judge {
		PanicWithErrorJson(err)
	}
}

func CheckRequestBody(context *gin.Context, obj interface{}) {
	var err error
	if context.Request.Method == "GET" {
		err = context.ShouldBindQuery(obj)
	} else {
		err = context.ShouldBindJSON(obj)
	}
	PanicWithErrorJsonWhenTrue(err != nil, "参数错误")
}

func GetRequestIpFlag() string {
	return "[requestIp:count]"
}

func GetFailIpFlag() string {
	return "[failIp:count]"
}

func GetBanIpFlag() string {
	return "[:banIpList]"
}

func ToRequestIp(ip string) string {
	return GetRequestIpFlag() + ip
}

func ToFailIp(ip string) string {
	return GetFailIpFlag() + ip
}

func ToTimeSecond(x int) time.Duration {
	return time.Duration(x) * time.Second
}

func GetLimitBucketFlag() string {
	return "[:limitBucketMap]"
}

func GetTodayTime(time int64) int64 {
	return time - (time - 16 *60 * 60 *1000) % (24 * 60 * 60 * 1000)
}
